﻿using System;
using System.IO;
using GC_FFW.BusinessEntities.Abstractions.Interfaces.Forecast;
using GC_FFW.BusinessEntities.Forecast.Xml;
using GC_FFW.Common.Abstractions.Interfaces.Helpers;
using GC_FFW.ForecastWriter.Abstractions.Adapters;
using GC_FFW.ForecastWriter.Abstractions.Interfaces.Factories;
using GC_FFW.ForecastWriter.Abstractions.Interfaces.Helpers;
using GC_FFW.ForecastWriter.Adapters.TeamMatch.ConfrontationsStatistics;
using GC_FFW.ForecastWriter.Adapters.TeamMatch.Introduction;
using GC_FFW.ForecastWriter.Adapters.TeamMatch.LastMatches;
using GC_FFW.ForecastWriter.Adapters.TeamMatch.LastTeamMatch;
using GC_FFW.ForecastWriter.Adapters.TeamMatch.Prognosis;
using GC_FFW.ForecastWriter.Enums;
using AwayTeam = GC_FFW.ForecastWriter.Adapters.TeamMatch.AwayTeamLastResults;
using HomeTeam = GC_FFW.ForecastWriter.Adapters.TeamMatch.HomeTeamLastResults;
using LastTeamMatch = GC_FFW.ForecastWriter.Adapters.TeamMatch.LastTeamMatch;
using Prognosis = GC_FFW.ForecastWriter.Adapters.TeamMatch.Prognosis;

namespace GC_FFW.ForecastWriter.Factories
{
	public class ProposalAdapterFactory : IProposalAdapterFactory
	{
		#region Variables

		private readonly IXmlSerializerService _xmlSerializerService;

		private readonly IStringManager _stringManager;

		private readonly IRandomizer _randomizer;

		private readonly IApplicationConfiguration _applicationConfiguration;

		#endregion

		#region Constructors

		public ProposalAdapterFactory(IXmlSerializerService xmlSerializerService, IStringManager stringManager,
			IRandomizer randomizer, IApplicationConfiguration applicationConfiguration)
		{
			if (xmlSerializerService == null)
				throw new ArgumentNullException(string.Format("Xml Serializer Service"));
			_xmlSerializerService = xmlSerializerService;

			if (stringManager == null)
				throw new ArgumentNullException(string.Format("String Manager"));
			_stringManager = stringManager;

			if (randomizer == null)
				throw new ArgumentNullException(string.Format("Randomizer"));
			_randomizer = randomizer;

			if (applicationConfiguration == null)
				throw new ArgumentNullException(string.Format("Application Configuration"));
			_applicationConfiguration = applicationConfiguration;
		}

		#endregion

		#region IProposalAdapterFactory Members

		public ProposalBaseAdapter Create(TeamMatchProposalType type, IForecastData forecastData)
		{
			var path = _applicationConfiguration.GetPath(type.ToString());
			Conditions data = null;
			if (!string.IsNullOrEmpty(path) && File.Exists(path))
				data = _xmlSerializerService.Deserialize<Conditions>(path);

			switch (type)
			{
				case TeamMatchProposalType.IntroductionWelcome:
					return new WelcomeProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.IntroductionBettingOptions:
					return new BettingOptionsProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.IntroductionAboutMatch:
					return new AboutMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.ConfrontationsStatisticsMatchesCount:
					return new MatchesCountProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.ConfrontationsStatisticsAboutWinner:
					return new AboutWinnerProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.ConfrontationsStatisticsAboutMatches:
					return new AboutMatchesProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.ConfrontationsStatisticsAboutWinnerResults:
					return new AboutWinnerResultsProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchLastMatchDate:
					return new LastMatchDateProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchGoalsCount:
					return new LastTeamMatch.GoalsCountProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchFirstGoal:
					return new FirstGoalProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchSecondGoal:
					return new SecondGoalProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchThirdGoal:
					return new ThirdGoalProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchFourthGoal:
					return new FourthGoalProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastTeamMatchConclusion:
					return new LastTeamMatch.ConclusionProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastMatchesIntroduction:
					return new IntroductionProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastMatchesTeamResults:
					return new TeamResultsProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastMatchesHomeTeamResults:
					return new HomeTeamResultsProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.LastMatchesAwayTeamResults:
					return new AwayTeamResultsProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.HomeTeamLastResultsFirstMatch:
					return new HomeTeam.FirstMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.HomeTeamLastResultsSecondMatch:
					return new HomeTeam.SecondMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.HomeTeamLastResultsThirdMatch:
					return new HomeTeam.ThirdMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.HomeTeamLastResultsFourthMatch:
					return new HomeTeam.FourthMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.HomeTeamLastResultsFifthMatch:
					return new HomeTeam.FifthMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.AwayTeamLastResultsFirstMatch:
					return new AwayTeam.FirstMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.AwayTeamLastResultsSecondMatch:
					return new AwayTeam.SecondMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.AwayTeamLastResultsThirdMatch:
					return new AwayTeam.ThirdMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.AwayTeamLastResultsFourthMatch:
					return new AwayTeam.FourthMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.AwayTeamLastResultsFifthMatch:
					return new AwayTeam.FifthMatchProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisTeamWinner:
					return new TeamWinnerProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisWinCoefficient:
					return new WinCoefficientProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisWinHandicapCoefficient:
					return new WinHandicapCoefficientProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisEventOfBothToScore:
					return new EventOfBothToScoreProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisGoalsCount:
					return new Prognosis.GoalsCountProposalAdapter(forecastData, data, _stringManager, _randomizer);

				case TeamMatchProposalType.PrognosisConclusion:
					return new Prognosis.ConclusionProposalAdapter(forecastData, data, _stringManager, _randomizer);

				default:
					throw new NotImplementedException(string.Format("Proposal Type is not implemented"));
			}
		}

		#endregion
	}
}
